package com.ewili.x.special.task.thread.impl;

import com.ewili.x.special.dao.inter.*;
import com.ewili.x.special.entity.Analysis;
import com.ewili.x.special.task.thread.inter.AnalysisThreadTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author wonder
 */
@Slf4j
@Component
public class AnalysisThreadTaskImpl implements AnalysisThreadTask {

    @Autowired
    private ResearchReportDao researchReportDao;

    @Autowired
    private AnalysisDao analysisDao;

    @Autowired
    private ExecsDao execsDao;

    @Autowired
    private AmountStockDao amountStockDao;

    @Autowired
    private HyRankDao hyRankDao;

    @Autowired
    private GoodWillDao goodWillDao;

    //@Async("myTaskAsyncPool")
    @Override
    public void analysis(String code, Date date) {
        //运算前进行当日数据修正
        Double socre = 0.0d;
        Double researchReportScore = this.researchReport(code, date);
        Double execsScore = this.execs(code, date);
        Double amountScore = this.amount(code, date);
        //Double hyRankScore = this.hyRank(code, date);
        Double goodWillScore = this.goodWill(code);

        socre += researchReportScore;
        socre += execsScore;
        socre += amountScore;
        //socre += hyRankScore;
        socre += goodWillScore;

        this.saveData(code, date, socre, researchReportScore, execsScore, amountScore);
    }

    /**
     * 保存数据
     *
     * @param code
     * @param date
     * @param socre
     */
    private void saveData(String code, Date date, Double socre, Double researchReportScore, Double execsScore, Double amountScore) {
        Analysis analysis = analysisDao.findByStockCodeAndDate(code, date);
        if (analysis == null) {
            analysis = new Analysis();
        }
        analysis.setDate(date);
        analysis.setSocre(socre);
        analysis.setStockCode(code);

        analysisDao.save(analysis);
    }


    /**
     * 原子因子 分析师研报
     *
     * @param code
     * @param date
     * @return
     */
    private Double researchReport(String code, Date date) {

        double researchReportScore = 0.0d;

        //夸克因子
        double reportFirstBuyOrHigher = researchReportDao.reportBuyOrHigherAndFirst(code, date);

        researchReportScore = reportFirstBuyOrHigher != 0 ? researchReportScore + 1 : 0;

        double reportBuyOrHigherAndUpper = researchReportDao.reportBuyOrHigherAndUpper(code, date);

        researchReportScore = reportBuyOrHigherAndUpper != 0 ? researchReportScore + 0.5 : researchReportScore;

        return researchReportScore;

    }

    /**
     * 原子因子 高管增减持
     *
     * @param code
     * @param date
     * @return
     */
    private Double execs(String code, Date date) {
        double execsScore = 0.0d;

        //夸克因子
        Double sumAmount = execsDao.sumAmountByDay(code, date);

        sumAmount = sumAmount == null ? 0.0d : sumAmount;

        execsScore = sumAmount > 0 ? execsScore + 1 : execsScore;

        execsScore = sumAmount < 0 ? execsScore - 1 : execsScore;
        return execsScore;
    }

    private Double amount(String code, Date date) {
        double amountScore = 0.0d;

        //夸克因子
        double amountAllBuy = 0.0d; //amountStockDao.amountAllBuy(code, date);

        amountScore = amountAllBuy > 0 ? amountScore + 1 : amountScore;

        double amountAllSell = 0.0d;//amountStockDao.amountAllSell(code, date);

        amountScore = amountAllSell > 0 ? amountScore - 1 : amountScore;

        return amountScore;
    }

    private Double hyRank(String code, Date date) {
        double hyRankScore = 0.0d;

        //夸克因子
        double lowValueHighGrowth = hyRankDao.lowValueHighGrowth(code, date);

        hyRankScore = lowValueHighGrowth > 0 ? hyRankScore + 1 : hyRankScore;


        double highValueLowGrowth = hyRankDao.highValueLowGrowth(code, date);

        hyRankScore = highValueLowGrowth > 0 ? hyRankScore + 1 : hyRankScore;
        return hyRankScore;
    }

    private Double goodWill(String code) {
        double highGoodWillScore = 0.0d;

        double highGoodWill = goodWillDao.highGoodWill(code);

        highGoodWillScore = highGoodWill != 0 ? highGoodWillScore - 1 : highGoodWillScore;

        return highGoodWillScore;
    }

}
